package com.ysw.io.数据分页;

import com.google.common.collect.Lists;

import java.util.List;

/**
 * @author: yu_sw
 * @Description: com.ysw.io.数据分页
 * @date:2022/5/17 15:54
 */
public class PartitionUtil {
    public static void main(String[] args) {
        List<PartitionIndexInfo> partitionIndexInfos = PartitionUtil.partitionForPSize(1001L, 1000L);
        System.out.println(partitionIndexInfos);
        /*List<PartitionIndexInfo> partitionIndexInfos1 = PartitionUtil.partitionForPNum(5L, 4);
        System.out.println(partitionIndexInfos1);*/
    }

    /**
     * 数据分批 ，给定分区大小，例： 1000个字节，我要固定100个一页
     *
     * @param length        数组长度
     * @param partitionSize 一个分片内容纳的元素个数
     * @return
     */
    public static List<PartitionIndexInfo> partitionForPSize(Long length, Long partitionSize) {
        List<PartitionIndexInfo> partitionIndexInfos = Lists.newArrayList();
        Boolean hasExtraPart = length % partitionSize != 0;
        Long basePartitionNum = length / partitionSize;
        // 存在余数说明多出一页
        Long partitionNum = hasExtraPart ? basePartitionNum + 1 : basePartitionNum;
        for (int i = 1; i <= partitionNum; i++) {
            Long start = (i - 1) * partitionSize;
            // index 位置从0开始，操作索引时注意 -1
            Long lastIndex = i * partitionSize - 1;
            Long maxIndex = length - 1;
            Long end = Math.min(lastIndex, maxIndex);
            partitionIndexInfos.add(new PartitionIndexInfo(start, end));
        }
        return partitionIndexInfos;
    }

    /**
     * 固定分片
     * @param length  数组大小
     * @param partitionNum 分片数量
     * @return
     */
    public static List<PartitionIndexInfo> partitionForPNum(Long length, int partitionNum) {
        List<PartitionIndexInfo> partitionIndexInfos = Lists.newArrayList();
        //计算出每个区最少容纳大小
        Long partitionSize = length / partitionNum;
        if(partitionSize == 0){
            throw new IllegalArgumentException("分片参数传递错误");
        }
        // 初始化每个分区索引信息
        for (int i = 1; i <= partitionNum; i++) {
            Long start = (i - 1) * partitionSize;
            // 如果最后一页直接使用最终索引
            Long end = i == partitionNum ? length - 1 : i * partitionSize - 1;
            partitionIndexInfos.add(new PartitionIndexInfo(start, end));
        }
        return partitionIndexInfos;
    }
}
